home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / net / bind-contrib.tar.gz / bind-contrib.tar / contrib / misc / dnsfind.shar / makehosts < prev    next >
Encoding:
Text File  |  1996-10-25  |  4.8 KB  |  229 lines

  1. #!/usr/local/bin/perl
  2. # makehosts -    Make a /etc/hosts file by searching DNS records
  3. #
  4. # $Id: dnsfind.shar,v 8.2 1996/10/25 17:07:55 vixie Exp $
  5. #
  6. # SYNOPSIS
  7. #    makehosts domain ...
  8. #
  9. # DESCRIPTION
  10. #    This program works by using dnsfind() to recursively search
  11. #    the desired domain(s) for all A, CNAME and PTR records.
  12. #    The output is sorted by IP-number, and it is ensured that any
  13. #    IP address will be translated to the name mentioned by its PTR
  14. #    record, if more than one name corresponds to the same address.
  15. #
  16. #    Note that the necessary PTR records must be provided by making
  17. #    makehosts search in the appropriate "IN-ADDR.ARPA" subdomains.
  18. #
  19. #    For example, if you want a hosts file for the domain
  20. #    "deakin.edu.au", you need to specify that domain, plus the
  21. #    reverse domains for any addresses corresponding to hosts in
  22. #    "deakin.edu.au".  You would need to say:
  23. #
  24. #       makehosts \
  25. #        deakin.edu.au \
  26. #        184.128.in-addr.arpa \
  27. #        132.139.in-addr.arpa
  28.  
  29.  
  30. push (@INC, '/src/config/util/perl');
  31.  
  32. require 'dnsfind.pl';
  33.  
  34. $Prog = substr ($0, rindex ($0, '/') + 1);
  35.  
  36. $Version = '$Revision: 8.2 $';
  37. @F = split (/\s+/, $Version);
  38. $Version = $F[1];
  39. undef @F;
  40.  
  41. #
  42. # Set the PATH, so we have a chance of finding "dig"
  43. #
  44. $ENV{'PATH'} = '/bin:/usr/bin:/usr/ucb:/usr/local/bin';
  45.  
  46. &main (@ARGV);
  47.  
  48. exit (0);
  49.  
  50.  
  51. ##############################################################################
  52. #
  53. sub main {
  54.     local (@domains);
  55.     local ($key, $value);
  56.     local ($not_canonical);
  57.     local (%done);
  58.     local (@addr);
  59.     local ($_);
  60.  
  61.     foreach (@_) {
  62.     tr/A-Z/a-z/;
  63.     push (@domains, $_);
  64.     }
  65.  
  66.     #
  67.     # Everybody needs localhost
  68.     #
  69.     $IN_A{'localhost.'} = '127.0.0.1';
  70.  
  71.     &dnsfind (@domains);
  72.  
  73.     #
  74.     # A records
  75.     #
  76.     warn "- Checking A records\n";
  77.  
  78.     while (($key, $value) = each (%IN_A)) {
  79.     undef %done;
  80.     @addr = split (/:/, $value);
  81.     foreach (@addr) {
  82.         next if ($done{$_});
  83.         $done{$_} = 1;
  84.         $not_canonical = 1;
  85.         #
  86.         # Check for matching PTR record
  87.         #
  88.         if (length ($IN_PTR{$_})) {
  89.         #
  90.         # A boolean that says this name is not the canonical
  91.         # name
  92.         #
  93.         $not_canonical =
  94.             (&strcasecmp ($key,
  95.                   substr($IN_PTR{$_}, 0, length ($key)))
  96.              != 0);
  97.         } else {
  98.         #
  99.         # Explicit lookup
  100.         #
  101.         if (! &dig (join ('.', reverse (split (/\./, $_)),
  102.                   'in-addr.arpa.'), "PTR")) {
  103.             warn "WARNING - no PTR for \"$_\" ($key A)\n";
  104.         }
  105.         }
  106.         push (@hosts, sprintf ("%03d.%03d.%03d.%03d %1d %s",
  107.                   split (/\./, $_), $not_canonical, $key));
  108.     }
  109.     }
  110.  
  111.     #
  112.     # CNAME records
  113.     #
  114.     while (($key, $value) = each (%IN_CNAME)) {
  115.     #
  116.     # Check that there is an A record
  117.     #
  118.     if (defined ($IN_A{$value})) {
  119.         @addr = split (/:/, $IN_A{$value});
  120.     } else {
  121.         #
  122.         # Explicit lookup
  123.         #
  124.         @addr = &dig ($value, 'A');
  125.         if (! @addr) {
  126.         warn "WARNING - no A record \"$value\" ($key CNAME)\n";
  127.         next;
  128.         }
  129.     }
  130.     undef %done;
  131.     foreach (@addr) {
  132.         next if ($done{$_});
  133.         $done{$_} = 1;
  134.         push (@hosts, sprintf ("%03d.%03d.%03d.%03d 2 %s",
  135.                    split (/\./, $_), $key));
  136.     }
  137.     }
  138.  
  139.     #
  140.     # PTR records
  141.     #
  142.     while (($key, $value) = each (%IN_PTR)) {
  143.     @h = split (/:/, $value);
  144.     foreach (@h) {
  145.         if (! defined ($IN_A{$_})) {
  146.         #
  147.         # Explicit lookup
  148.         #
  149.         if (! &dig ($_, "A")) {
  150.             warn "WARNING - no A record \"$_\" ($key PTR)\n";
  151.         }
  152.         }
  153.     }
  154.     }
  155.  
  156.     #
  157.     # Sort @hosts
  158.     #
  159.     @hosts = sort (@hosts);
  160.  
  161.     #
  162.     # Output hosts
  163.     #
  164.     $date_time = `date`; chop ($date_time);
  165.     print (
  166. '# hosts -    host-name/IP-address data base
  167. #
  168. # $Source: /proj/src/isc/cvs-1/bind/contrib/misc/dnsfind.shar,v $
  169. #
  170. # This file generated by ' . "\"$Prog\" $Version, on $date_time" . '
  171. # Domains searched:
  172. #    ' . join ("\n#\t", @domains) . '
  173. #
  174. ');
  175.  
  176.     foreach (@hosts) {
  177.     ($address, $dummy, $name) = split;
  178.     $address = sprintf ("%d.%d.%d.%d", split (/\./, $address));
  179.  
  180.     #
  181.     # Trim the trailing dot
  182.     #
  183.     $name =~ s/\.$//;
  184.  
  185.     #
  186.     # Due to the edu.au, zone being officially known as EDU.AU, all
  187.     # data for all domains under this zone is returned with EDU.AU,
  188.     # in all uppercase, by DNS.  We don't like this in /etc/hosts,
  189.     # so we will endeavour to fold to lowercase here.
  190.     #
  191.     $name =~ s/EDU.AU$/edu.au/i;
  192.  
  193.     $short = $name;
  194.     $short =~ s/\..*$//;
  195.  
  196.     print ($address, "\t");
  197.     if (length ($address) < 8) {
  198.         print ("\t");
  199.     }
  200.     print ($name, "\t");
  201.     if (length ($name) < 24) {
  202.         print ("\t");
  203.     }
  204.     print ($short, "\n");
  205.     }
  206.     return 0;
  207. }
  208.  
  209.  
  210. ##############################################################################
  211. #
  212. sub dnswanted {
  213.     if ($Parent ne $parent_zone) {
  214.     warn "- Searching $parent_zone, from $server\n";
  215.     $Parent = $parent_zone;
  216.     }
  217.  
  218.     if ($type eq 'A') {
  219.     $IN_A{$zone} .= $value . ':';
  220.     } elsif ($type eq 'CNAME') {
  221.     $IN_CNAME{$zone} = $value;
  222.     } elsif ($type eq 'PTR') {
  223.     $address = $zone;
  224.     $address =~ s/\.in-addr\.arpa\.?$//i;
  225.     $address = join ('.', reverse (split (/\./, $address)));
  226.     $IN_PTR{$address} .= $value . ':';
  227.     }
  228. }
  229.